<!--
 * @Description: 选择树
-->
<template>
  <div class="cpt_grey_disabled" v-if="disabled">{{
    Array.isArray(value)
      ? value
          .map(i => {
            return i[prop['label']]
          })
          .join('，')
      : value[label_p]
  }}</div>
  <el-select
    v-else
    :ref="select_tree"
    class="_ehl_select_tree"
    popper-class="cpt_select_tree_pop"
    :value="labels"
    @clear="clearItem"
    @visible-change="visibleChange"
    :filter-method="remoteMethod"
    :placeholder="placeholder"
    :loading="loading"
    :loading-text="loadingtext"
    :disabled="disabled"
    :clearable="clearable"
    :filterable="filterable"
  >
    <el-option :label="labels" :value="labels">
      <el-tree
        :ref="select_tree_item"
        :data="tree"
        :props="prop"
        :show-checkbox="showCheckbox"
        :default-expand-all="defaultExpandAll"
        :node-key="value_p"
        :check-strictly="checkStrictly"
        :expand-on-click-node="expandOnClickNode"
        :indent="indent"
        :accordion="accordion"
        @check-change="checkChange"
        @node-click="nodeClick"
      ></el-tree>
    </el-option>
  </el-select>
</template>
<script>
  import Vue from 'vue'
  import { Select, Option, Tree } from 'element-ui'
  Vue.use(Select)
  Vue.use(Option)
  Vue.use(Tree)
  export default {
    props: {
      value: { type: Array, required: true, default: () => [] },
      tree: { type: Array, required: true, default: () => [] },
      //懒加载，false=创建时加载，true=下拉框出现时加载
      lazy: { type: Boolean, default: () => false },
      //显示清空按钮
      clearable: { type: Boolean, default: () => false },
      //是否遵循父子不互相关联
      checkStrictly: { type: Boolean, default: () => false },
      //是否不可编辑
      disabled: { type: Boolean, default: () => false },
      //是否启动搜索,启动后默认为lazy状态
      filterable: { type: Boolean, default: () => false },
      //是否启动多选框
      showCheckbox: { type: Boolean, default: () => true },
      //相邻级节点间的水平缩进
      indent: { type: Number, default: () => 16 },
      //是否开启手风琴模式
      accordion: { type: Boolean, default: () => false },
      //字段分隔符
      devide: { type: String, default: () => ',' },
      //是否在点击节点的时候展开或者收缩节点
      expandOnClickNode: { type: Boolean, default: () => false },
      //树一开始是否全部展开
      defaultExpandAll: { type: Boolean, default: () => true },
      //是否只能点击叶子节点
      onlyLeafNodeCanClick: { type: Boolean, default: () => false },
      placeholder: { type: String, default: () => '请选择' },
      loadingtext: { type: String, default: () => '加载中...' },
      //value的key映射
      prop: {
        type: Object,
        default: () => ({
          label: 'label',
          value: 'value',
          children: 'children',
          disabled: 'disabled',
          isLeaf: 'leaf',
        }),
      },
    },
    data() {
      return {
        loading: false,
        label_p: this.prop['label'],
        value_p: this.prop['value'],
        children_p: this.prop['children'],
        select_tree: `select_tree_ref_${Math.random()}`,
        select_tree_item: `select_tree_item_ref_${Math.random()}`,
      }
    },
    computed: {
      labels() {
        return this.getLabel(this.value).join(this.devide)
      },
    },
    watch: {
      //值更新的时候，更新选中状态
      value: {
        handler: function (val, old) {
          this.valueToTree(val)
        },
        deep: true,
      },
      //树更新的时候，更新选中状态
      tree: {
        handler: function (val, old) {
          this.valueToTree(this.value)
        },
        deep: true,
      },
    },
    created() {
      !(this.filterable || this.lazy) && !this.disabled && this.$emit('init', this.tree)
    },
    methods: {
      //清空值和树
      clearItem() {
        this.$emit('input', [])
        this.$emit('change', [])
        this.$refs[this.select_tree_item].setCheckedKeys([])
      },
      //勾选后的值传递出去
      checkChange() {
        if (this.showCheckbox) {
          let tmp = this.$refs[this.select_tree_item].getCheckedNodes().filter(i => {
            return i.ignore !== true
          })
          this.$emit('input', tmp)
          this.$emit('change', tmp)
        }
      },
      //点击后值传递出去
      nodeClick(data) {
        if (!this.showCheckbox) {
          if (this.onlyLeafNodeCanClick) {
            if (!data[this.children_p]) {
              this.$emit('input', [data])
              this.$emit('change', [data])
            }
          } else {
            this.$emit('input', [data])
            this.$emit('change', [data])
          }
          this.$refs[this.select_tree].blur()
        }
      },
      //把数据在树中勾选
      valueToTree(value) {
        let tmp = isEmpty(value)
          ? []
          : value.map(i => {
              return i[this.value_p]
            })
        this.$nextTick(() => {
          this.$refs[this.select_tree_item].setCheckedKeys(tmp)
          this.loading = false
        })
      },
      //组合显示文字
      getLabel(val) {
        let tmp = []
        val.forEach(i => {
          if (i.ignore !== true) {
            tmp.push(i[this.label_p])
          }
        })
        return tmp
      },
      visibleChange(val) {
        if ((this.filterable || this.lazy) && val && !this.disabled) {
          this.loading = true
          this.$emit('init', this.tree)
        }
      },
      remoteMethod(val) {
        this.$emit('init', this.tree, val)
      },
    },
  }
</script>
